const modes = ["NN", "NNWJ", "SS", "SSWJ"];

const policyCompute = (source, length, detail = true) => {
  let policy = modes.map((mode) => {
    let content = new Array(length).fill(null);
    let recommend = new Array(length).fill(null);
    let fallback = new Array(length).fill(null);
    let replacement = new Array(length).fill(null);
    let overloaded = new Array(length).fill(false);
    let optimized = new Array(length).fill(false);
    let count = 0;
    source.forEach((res) => {
      if (res.modes.includes(mode)) {
        for (let i = 0; i < length; i++) {
          if (content[i] == null) {
            content[i] = new Array();
          }
          let item = {
            title: res.title,
            areas: res.areas,
            models: res.models,
            evaluation: {
              evaluationOriginalQuarter:
                res.evaluation.evaluationOriginalQuarter[i],
              evaluationOriginalWhole:
                res.evaluation.evaluationOriginalWhole[i],
              evaluationOriginalMixed:
                (res.evaluation.evaluationOriginalQuarter[i] +
                  res.evaluation.evaluationOriginalWhole[i]) /
                2,
              evaluationCalibratedQuarter:
                res.evaluation.evaluationCalibratedQuarter[i],
              evaluationCalibratedWhole:
                res.evaluation.evaluationCalibratedWhole[i],
              evaluationCalibratedMixed:
                (res.evaluation.evaluationCalibratedQuarter[i] +
                  res.evaluation.evaluationCalibratedWhole[i]) /
                2,
              evaluationMixed:
                (res.evaluation.evaluationOriginalQuarter[i] +
                  res.evaluation.evaluationOriginalWhole[i] +
                  res.evaluation.evaluationCalibratedQuarter[i] +
                  res.evaluation.evaluationCalibratedWhole[i]) /
                4,
            },
            // areaDetails: detail ? res.areaDetails[i] : [],
            areaDetails: res.areaDetails[i],
            areaTagDetails: res.areaTagDetails[i],
          };
          if (item.evaluation.evaluationMixed >= 0) {
            content[i].push(item);
            count++;
          }
          if (
            fallback[i] == null ||
            fallback[i].areas.length < item.areas.length
          ) {
            fallback[i] = item;
          }
        }
      }
    });
    // console.log("policyCompute", mode, length, source.length, count);
    for (let i = 0; i < length; i++) {
      // console.log("policyCompute", mode, i, content[i].length);
      if (content[i] != null && content[i].length > 0) {
        content[i].sort(function (a, b) {
          return b.evaluation.evaluationCalibratedMixed ==
            a.evaluation.evaluationCalibratedMixed ||
            (Math.abs(
              b.evaluation.evaluationCalibratedQuarter -
                a.evaluation.evaluationCalibratedQuarter
            ) < 50 &&
              Math.abs(
                b.evaluation.evaluationCalibratedWhole -
                  a.evaluation.evaluationCalibratedWhole
              ) < 150)
            ? a.areas.length - b.areas.length
            : b.evaluation.evaluationCalibratedMixed -
                a.evaluation.evaluationCalibratedMixed;
        });
        if (content[i].length > 3) {
          content[i] = content[i].slice(0, 3);
        }
        recommend[i] = content[i][0];
      } else {
        overloaded[i] = true;
        recommend[i] = fallback[i];
      }
    }

    return {
      mode,
      recommend,
      content,
      fallback,
      replacement,
      overloaded,
      optimized,
    };
  });
  policy = postOptimize(policy);
  // policy = postOptimize(policy);
  return policy;
};

const postOptimize = (policy, reviewCount = 1, previewCount = 2) => {
  policy.forEach((pValue, pIndex, pArray) => {
    pArray[pIndex].recommend.forEach((cValue, cIndex, cArray) => {
      for (let i = cIndex - reviewCount; i <= cIndex + previewCount; i++) {
        if (
          i >= 0 &&
          i < cArray.length &&
          i != cIndex &&
          !pArray[pIndex].optimized[i]
        ) {
          if (cArray[cIndex].areas.length < cArray[i].areas.length) {
            policy[pIndex].replacement[cIndex] = cArray[i];
            policy[pIndex].recommend[cIndex] = cArray[i];
            policy[pIndex].optimized[cIndex] = true;
          }
        }
      }
    });
  });
  return policy;
};

export default policyCompute;
